//
//  DUMonthDayView.swift
//  SimpleCal
//
//  Created by 杜晓祥 on 2021/10/20.
//

import Cocoa

@IBDesignable
class DUMonthDayView: NSView, DUMonthDayProtocol, SimpleChangeHandler {
    
    private var dayGroup = RadioGroup<DUDayView>()
    
    private let weekValue = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]
    
    private var currentDate:DateEntity!
    var weekLabel = [DULabel]()
    
    override init(frame frameRect: NSRect) {
        super.init(frame: frameRect)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        initialize()
    }
    
    private func initialize () {
        dayGroup.change = self

        var x = 5
        for w in weekValue {
            let l = DULabel()
            l.frame = NSRect(x: x, y: 330, width: 50, height: 20)
            l.font = NSFont.systemFont(ofSize: 18)
            l.stringValue = w
            addSubview(l)
            weekLabel.append(l)
            x += 53
        }
        var y = 270
        for _ in (0...5) {
            var x = 5
            for _ in (0...6) {
                let  d = DUDayView()
                d.frame = NSRect(x: x, y: y, width: 50, height: 50)
                dayGroup.addSubview(view: d)
                self.addSubview(d)
                x += 53
            }
            y -= 53
        }
    }
    
    func onChange(_ params: NSObject?) {
        let p = params as! DUDayView
        let pd = p.date!
        GlobalControl.shared.dayDetail?.update(date: pd)
    }
    
    func update(date: DateEntity) {
        currentDate = date
        addPreDate(date: currentDate)
        addCurrentDate(date: currentDate)
        addNextDate(date: currentDate)
    }
    
    func currentMonth() {
        currentDate = CalendarUtil.getNowDateEntity()
        addPreDate(date: currentDate)
        addCurrentDate(date: currentDate)
        addNextDate(date: currentDate)
    }
    
    func prevPage() {
        currentDate = CalendarUtil.monthDec(date: currentDate)
        addPreDate(date: currentDate)
        addCurrentDate(date: currentDate)
        addNextDate(date: currentDate)
    }
    
    func nextPage() {
        currentDate = CalendarUtil.monthInc(date: currentDate)
        addPreDate(date: currentDate)
        addCurrentDate(date: currentDate)
        addNextDate(date: currentDate)
    }
    
    func setMonth(year: Int, month: Int) {
        currentDate = CalendarUtil.getDateEntity(year: year, month: month)
        addPreDate(date: currentDate)
        addCurrentDate(date: currentDate)
        addNextDate(date: currentDate)
    }
    
    func setPage(pageType: PageSwitchEnum, year: Int, month:Int, completionHandler completion: ((PageTypeModel?) -> Void)) {
        
    }
    
    private func addCurrentDate(date:DateEntity) {
        let s = date.solar
        var dayIndex = s.week - 1
        var i = 1
        while i <= CalendarUtil.getMonthDays(year: s.year, month: s.month) {
            var v = dayGroup.getSubview(index: dayIndex)
            v.setDefaultDay(date: CalendarUtil.getDateEntity(year: s.year, month: s.month, day: i))
            mouseCurrentMonth(day: &v)
            v.selected = false
            v.setStyle(v.defaultStyle)
            v.defaultSelect = false
            var style = currentMonthStyle()
            if v.isWeekend() {
                weekStyle(style: &style)
            }
            v.setStyle(style: style)
            i += 1
            dayIndex += 1
        }
        if CalendarUtil.isCurrentMonth(date: date) {
            let day = CalendarUtil.getNowDate()
            var v = dayGroup.getSubview(index: (s.week + day.day - 2))
            mouseToday(day: &v)
            v.setStyle(v.mouseDownStyle)
        }
    }
    
    private func addPreDate (date: DateEntity) {
        //var s = date.solar
        var dayIndex = date.solar.week - 2
        let s = CalendarUtil.monthDec(date: date)//.monthDec(solar: s)
        var day = CalendarUtil.getMonthDays(year: s.solar.year, month: s.solar.month)
        while dayIndex >= 0 {
            var v = dayGroup.getSubview(index: dayIndex)
            v.setDefaultDay(date: CalendarUtil.getDateEntity(year: s.solar.year, month: s.solar.month, day: day))
            v.defaultSelect = false
            v.selected = false
            v.setStyle(v.defaultStyle)
            mousePreMonth(day: &v)
            var style = preMonthStyle()
            if v.isWeekend() {
                weekStyle(style: &style)
            }
            v.setStyle(style: style)
            dayIndex -= 1
            day -= 1
        }
        
        if CalendarUtil.isCurrentMonth(date: s) {
            let solar = CalendarUtil.getNowDate()
            if day < solar.day {
                var v = dayGroup.getSubview(index: solar.day - day - 1)
                mouseToday(day: &v)
                v.setStyle(v.mouseDownStyle)
            }
        }
    }
    
    private func addNextDate (date: DateEntity) {
        //var s = date.solar
        var dayIndex = date.solar.week + CalendarUtil.getMonthDays(year: date.solar.year, month: date.solar.month) - 1
        let s = CalendarUtil.monthInc(date: date)//.monthInc(solar: s)
        var day = 1
        while  dayIndex < dayGroup.count() {
            var v = dayGroup.getSubview(index: dayIndex)
            v.setDefaultDay(date: CalendarUtil.getDateEntity(year: s.solar.year, month: s.solar.month, day: day))
            mouseNextMonth(day: &v)
            v.defaultSelect = false
            v.selected = false
            v.setStyle(v.defaultStyle)
            var style = nextMonthStyle()
            if v.isWeekend() {
                weekStyle(style: &style)
            }
            v.setStyle(style: style)
            dayIndex += 1
            day += 1
        }
        if CalendarUtil.isCurrentMonth(date: s) {
            let solar = CalendarUtil.getNowDate()
            if day > solar.day {
                let i = dayIndex - day + solar.day - 1
                var v = dayGroup.getSubview(index: i)
                mouseToday(day: &v)
                v.setStyle(v.mouseDownStyle)
            }
        }
    }
    
    /**
     上一月样式
     */
    private func preMonthStyle() -> DayColorModel {
        var style = DayColorModel()
        style.lunarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.solarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.maskColor = NSColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.2)
        style.maskIsHidden = false
        return style
    }
    
    /**
     显示下一月样式
     */
    private func nextMonthStyle() -> DayColorModel {
        var style = DayColorModel()
        style.lunarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.solarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.maskColor = NSColor(red: 0.5, green: 0.5, blue: 0.5, alpha: 0.3)
        style.maskIsHidden = false
        return style
    }
    /**
     当前月样式
     */
    private func currentMonthStyle() -> DayColorModel {
        var style = DayColorModel()
        style.lunarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.solarForegroundColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 1)
        style.maskColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 0.5)
        style.maskIsHidden = true
        return style
    }
    
    /**
     星期六、星期日样式
     */
    private func weekStyle(style: inout DayColorModel) {
        style.solarForegroundColor = NSColor(red: 0.96, green: 0.2, blue: 0.2, alpha: 1)
        //style.maskColor = NSColor(red: 0.3, green: 0.3, blue: 0.3, alpha: 0.5)
        //style.maskHidden = true
    }
    
    private func mousePreMonth (day: inout DUDayView) {
        day.defaultStyle = BaseView.ViewStyleUtil.dayDefaultStyle()
        day.mouseDownStyle = BaseView.ViewStyleUtil.notCurrentMonthDownStyle()
        day.mouseEnteredStyle = BaseView.ViewStyleUtil.notCurrentMonthEnteredStyle()
    }
    
    private func mouseNextMonth (day: inout DUDayView) {
        day.defaultStyle = BaseView.ViewStyleUtil.dayDefaultStyle()
        day.mouseDownStyle = BaseView.ViewStyleUtil.notCurrentMonthDownStyle()
        day.mouseEnteredStyle = BaseView.ViewStyleUtil.notCurrentMonthEnteredStyle()
    }
    
    private func mouseCurrentMonth (day: inout DUDayView) {
        day.defaultStyle = BaseView.ViewStyleUtil.dayDefaultStyle()
        day.mouseDownStyle = BaseView.ViewStyleUtil.dayDownStyle()
        day.mouseEnteredStyle = BaseView.ViewStyleUtil.dayEnteredStyle()
    }

    private func mouseToday (day: inout DUDayView) {
        day.defaultStyle = BaseView.ViewStyleUtil.dayCurrentExitStyle()
        day.mouseDownStyle = BaseView.ViewStyleUtil.dayCurrentStyle()
        day.mouseExitStyle = BaseView.ViewStyleUtil.dayCurrentExitStyle()
        day.mouseEnteredStyle = BaseView.ViewStyleUtil.dayCurrentStyle()
        day.defaultSelect = true
    }
    
}
